using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

using Oarw.General;

namespace ScreenMonkey.Plugin.Clips.Song
{
    public partial class LyricsInput : UserControl, ICopyAndPaste, IEdit
    {
        private Dictionary<String,VerseLabel> highlightedItems = new Dictionary<String,VerseLabel>();
        private bool loading = false;

        public event EventHandler VerseCountChanged;

        public LyricsInput()
        {
            InitializeComponent();
        }


        private SongLyrics lyrics = null;

        public SongLyrics Lyrics
        {
            get 
            {
                UpdateWords();
                return lyrics;
            }
            set {
                if (lyrics != value)
                {
                    lyrics = value;
                    LoadWords();

                    Modified = false;
                }
                 
            }
        }

        private string lastWords = null;
        private void UpdateWords()
        {
            if (lyrics != null && words != null)
            {
                if (lastWords == null || lastWords != words.Text)
                {
                    lastWords = words.Text;
                    lyrics.UpdateWords(words.Text);
                }                
            }
        }

        private void LoadWords()
        {
            loading = true;

            string songWords = "";

            if (lyrics != null)
            {
                foreach (KeyValuePair<VerseLabel, VerseLyrics> verse in lyrics.Verses)
                {
                    songWords += verse.Key.Name;
                    songWords += "\n\n";
                    songWords += verse.Value.Words.Trim();
                    songWords += "\n\n";


                }

                words.Text = songWords;
                InvalidateHighlights();
            }

            loading = false;

        }
        
        public void HighlightTitles()
        {
            VerseLabel label = null;
            int saveSelect;
            int countHighlight = 0;
            int oldHighlightCount = highlightedItems.Count;
            Dictionary<String, VerseLabel> allHighlights = new Dictionary<String, VerseLabel>();

            int cursor = 0;
            foreach (string line in words.Lines)
            {
                if(!allHighlights.ContainsKey(line))        //Prevent a label from being read twice. Only highlight the first ocurrance of a label.
                {
                    if (!highlightedItems.ContainsKey(line))
                    {
                        if (VerseLabel.TryParse(line, out label))
                        {
                            saveSelect = words.SelectionStart;

                            words.Select(cursor, line.Length);
                            words.SelectionBackColor = Color.FromArgb(210, 210, 255);
                            words.SelectionFont = new Font(words.SelectionFont, FontStyle.Bold);
                            words.DeselectAll();

                            words.Select(saveSelect, 0);
                            RemoveHighlight();

                            highlightedItems.Add(line, label);
                            countHighlight++;

                            //Force the song words to be updated so the sequence is changed.
                            UpdateWords();
                        }

                    }
                    else
                    {
                        countHighlight++;
                    }

                    allHighlights.Add(line, null);
                }

                cursor += line.Length + 1;
            }

            if (countHighlight != highlightedItems.Count)
            {
                InvalidateHighlights();
            }

            if(oldHighlightCount!=countHighlight)
            {
                if(VerseCountChanged != null) VerseCountChanged(this, EventArgs.Empty);
            }
        }

        private void InvalidateHighlights()
        {
            int saveSelect = words.SelectionStart; ;

            highlightedItems.Clear();
            words.SelectAll();
            RemoveHighlight();

            words.Select(saveSelect, 0);

            HighlightTitles();
        }

        private void RemoveHighlight()
        {
            words.SelectionBackColor = Color.Transparent;
            words.SelectionFont = new Font(words.SelectionFont, FontStyle.Regular);
        }

        private void words_TextChanged(object sender, EventArgs e)
        {
            HighlightTitles();
            Modified = true;
        }




        #region ICopyAndPaste Members

        public void Cut()
        {
            words.Cut();
        }

        public void Copy()
        {
            words.Copy();
        }

        public void Paste()
        {   
            words.Paste(DataFormats.GetFormat(DataFormats.Text));
        }

        public void SelectAll()
        {
            words.SelectAll();
        }

        #endregion

        #region IEdit Members

        public event EventHandler ModifiedChanged;

        private bool modified = false;

        public bool Modified
        {
            get { return modified; }
            set
            {
                if (modified != value && !loading)
                {
                    modified = value;
                    if (ModifiedChanged != null ) ModifiedChanged(this, EventArgs.Empty);
                }

            }
        }

        #endregion

        private void editMenuCut_Click(object sender, EventArgs e)
        {
            Cut();
        }

        private void editMenuCopy_Click(object sender, EventArgs e)
        {
            Copy();
        }

        private void editMenuPaste_Click(object sender, EventArgs e)
        {
            Paste();
        }

        private void editMenuSelectAll_Click(object sender, EventArgs e)
        {
            SelectAll();
        }

        private void editMenu_Opening(object sender, CancelEventArgs e)
        {
            // check to see if we can cut/copy, paste anything; then enable/disable menu items
            // as required
            IDataObject iData=Clipboard.GetDataObject();
            editMenuPaste.Enabled = iData.GetDataPresent(DataFormats.Text);
            if (words.SelectionLength==0) {
                editMenuCut.Enabled = false;
                editMenuCopy.Enabled = false;
            }
            else {
                editMenuCut.Enabled = true;
                editMenuCopy.Enabled = true;
            }
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            switch (keyData)
            {
                case Keys.Control | Keys.V:
                case Keys.Shift | Keys.Insert:
                    Paste();
                    return true;
                default:
                    return base.ProcessCmdKey(ref msg, keyData);
            }            
        }
    }
}
